package com.yokead.controller.shield;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.http.HttpUtil;
import cn.jiangzeyin.StringUtil;
import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.common.spring.SpringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yokead.common.Config;
import com.yokead.common.base.AdminBaseControl;
import com.yokead.common.tools.UrlPath;
import com.yokead.controller.copy.CopyIndexControl;
import com.yokead.controller.rewrite.RewriteIndexControl;
import com.yokead.service.rewrite.ConfService;
import com.yokead.service.rewrite.EditRewriteServer;
import com.yokead.shield.ShieldUtil;
import com.yokead.system.log.LogType;
import com.yokead.system.log.SystemLog;
import com.yokead.util.EncryptUtil;
import com.yokead.util.JsonUtil;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;

/**
 * 屏蔽系统
 * Created by jiangzeyin on 2017/9/6.
 */
@Controller
@RequestMapping("shield")
public class ShieldIndexControl extends AdminBaseControl {

    @Resource
    private EditRewriteServer editRewriteServer;

    @Resource
    private ConfService confService;

    @RequestMapping(value = "index.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String index(String name) throws IOException {
        setAttribute("data", CopyIndexControl.getInfo(UrlPath.Type.None, name, Config.Nginx.getNginxConfigPath()));
        JSONArray jsonArray = ShieldUtil.getJsonArray();
        setAttribute("array", jsonArray);
        return "shield/index";
    }

    @RequestMapping(value = "add.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String add(String url) throws IOException {
        String title = "添加屏蔽";
        setAttribute("title", title);
        boolean find = false;
        String confPath = null;
        // 判断跳转状态
        JSONObject jsonObject = RewriteIndexControl.all(null, Config.Nginx.getNginxConfigPath());
        if (jsonObject != null) {
            Collection<Object> collection = jsonObject.values();
            in:
            for (Object object : collection) {
                JSONArray jsonArray = (JSONArray) object;
                for (Object aJsonArray : jsonArray) {
                    JSONObject item = (JSONObject) aJsonArray;
                    String item_url = item.getString("url");
                    if (("http://" + item_url).equals(url)) {
                        find = item.getBooleanValue("ing");
                        confPath = item.getString("confPath");
                        break in;
                    }
                }
            }
            if (find) {
                setAttribute("tip", "该链接已经存在跳转，如果需要屏蔽，请先取消跳转");
                return "shield/add";
            }
            if (StringUtil.isEmpty(confPath)) {
                setAttribute("tip", "链接配置存在异常，请联系管理员");
                return "shield/add";
            }
        }
        // 判断是否存在两种文案
        JSONObject status_json = CopyIndexControl.getInfo(UrlPath.Type.Status, null, Config.Nginx.getNginxConfigPath());
        String status = null;
        String urlPath = null;
        if (status_json != null) {
            Collection<Object> collection1 = status_json.values();
            in:
            for (Object object : collection1) {
                JSONArray jsonArray = (JSONArray) object;
                for (Object aJsonArray : jsonArray) {
                    JSONObject item = (JSONObject) aJsonArray;
                    String item_url = item.getString("url");
                    if (("http://" + item_url).equals(url)) {
                        find = true;
                        status = item.getString("status");
                        urlPath = item.getString("urlPath");
                        break in;
                    }
                }
            }
            if (!find) {
                setAttribute("tip", "该链接没有两种文案状态，请先添加对应审核或者投放页面");
                return "shield/add";
            }
        }
        if (StringUtil.isEmpty(status) || StringUtil.isEmpty(urlPath)) {
            setAttribute("tip", "链接状态异常，请联系管理员");
            return "shield/add";
        }
        title = "修改屏蔽";
        setAttribute("title", title);
        setAttribute("item", ShieldUtil.getObj(url));
        setAttribute("urlPath", urlPath);
        setAttribute("confPath", confPath);
        setAttribute("status", status);
        return "shield/add";
    }

    @RequestMapping(value = "cancel.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String cancel(String url) {
        JSONObject jsonObject;
        try {
            jsonObject = ShieldUtil.getObj(url);
            if (jsonObject == null) {
                return JsonMessage.getString(400, "没有对应链接");
            }
        } catch (IOException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("获取信息异常", e);
            return JsonMessage.getString(400, "获取信息异常");
        }
        String confPath = jsonObject.getString("confPath");
        RewriteIndexControl rewriteIndexControl = SpringUtil.getBean(RewriteIndexControl.class);
        String[] tags = rewriteIndexControl.check(url, confPath);
        if (tags[0] != null) {
            return tags[0];
        }
        StringBuffer stringBuffer = editRewriteServer.delRewrite(tags[1], tags[2], true);
        if (stringBuffer == null) {
            return JsonMessage.getString(404, "取消屏蔽接口处理异常，-1");
        }
        // 写入文件
        try {
            FileUtil.writeString(stringBuffer.toString(), tags[2], CharsetUtil.CHARSET_UTF_8);
        } catch (IORuntimeException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("保存取消接口处理异常：-2", e);
            return JsonMessage.getString(404, "保存取消接口处理异常：-2");
        }
        confService.reload(userName + " 操作了取消" + url + "地区屏蔽");
        try {
            delJson(jsonObject);
        } catch (IOException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("保存取消接口json", e);
            return JsonMessage.getString(404, "保存取消接口json");
        }
        String id = jsonObject.getString("id");
        File path = new File(ShieldUtil.getShieldConfPath(), id);
        FileUtil.clean(path);
        return doApi(id);
    }

    @RequestMapping(value = "add.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String addJson(String url, String urlPath, String confPath, String tf, String pb, String region, String city) {
        if (StringUtil.isEmpty(region) && StringUtil.isEmpty(city)) {
            return JsonMessage.getString(400, "请输入需要屏蔽的城市信息");
        }
        // 验证url
        RewriteIndexControl rewriteIndexControl = SpringUtil.getBean(RewriteIndexControl.class);
        String[] tags = rewriteIndexControl.check(url, confPath);
        if (tags[0] != null) {
            return tags[0];
        }
        String path;
        File parent;
        try {
            path = EncryptUtil.decrypt(urlPath);
            parent = new File(path);
            if (!parent.exists()) {
                return JsonMessage.getString(404, "不存在屏蔽配置");
            }
        } catch (Exception e1) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("屏蔽配置读取异常", e1);
            return JsonMessage.getString(404, "屏蔽配置读取异常");
        }
        tf = convertFilePath(tf);
        pb = convertFilePath(pb);
        File tfFile = new File(parent, tf);
        if (!tfFile.exists()) {
            return JsonMessage.getString(404, "不存在对应页面关系：tf," + tf);
        }
        File pbFile = new File(parent, pb);
        if (!pbFile.exists()) {
            return JsonMessage.getString(404, "不存在对应页面关系：pb," + pb);
        }
        JSONObject jsonObject;
        try {
            jsonObject = ShieldUtil.getObj(url);
        } catch (IOException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("屏蔽配置读取异常:2", e);
            return JsonMessage.getString(404, "屏蔽配置读取异常:2");
        }
        if (jsonObject == null) {
            jsonObject = new JSONObject();
            jsonObject.put("url", url);
            jsonObject.put("id", UUID.randomUUID().toString().toUpperCase());
        }
        String[] region_s = StringUtil.stringToArray(region, "\r\n");
        String[] city_s = StringUtil.stringToArray(city, "\r\n");
        jsonObject.put("tf", tf);
        jsonObject.put("pb", pb);
        jsonObject.put("region", JSONArray.toJSON(region_s));
        jsonObject.put("city", JSONArray.toJSON(city_s));
        jsonObject.put("lastModifyTime", System.currentTimeMillis());
        jsonObject.put("confPath", confPath);
        try {
            saveJson(jsonObject);
        } catch (IOException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("屏蔽配置保存异常", e);
            return JsonMessage.getString(404, "屏蔽配置保存异常");
        }
        String id = jsonObject.getString("id");
        // 复制文案
        File canFile = new File(ShieldUtil.getShieldConfPath(), id + "/can.vm");
        if (!canFile.getParentFile().exists()) {
            if (!canFile.getParentFile().mkdirs()) {
                return JsonMessage.getString(404, "创建文件1异常");
            }
        }
        File notCanFile = new File(ShieldUtil.getShieldConfPath(), id + "/notCan.vm");
        if (!notCanFile.getParentFile().exists()) {
            if (!notCanFile.getParentFile().mkdirs()) {
                return JsonMessage.getString(404, "创建文件2异常");
            }
        }
        try {
            FileCopyUtils.copy(tfFile, canFile);
            FileCopyUtils.copy(pbFile, notCanFile);
        } catch (IOException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("屏蔽配置文件信息异常", e);
            return JsonMessage.getString(404, "屏蔽配置文件信息异常");
        }
        if (!canFile.exists() || !notCanFile.exists()) {
            return JsonMessage.getString(404, "结束文件信息异常");
        }
        // 添加nginx 配置
        StringBuffer loc = createLocation(tags[1], id);
        StringBuffer stringBuffer = editRewriteServer.delRewrite(tags[1], tags[2], true);
        if (stringBuffer == null) {
            return JsonMessage.getString(404, "屏蔽配置接口处理异常，-1");
        }
        int end = stringBuffer.lastIndexOf("}");
        stringBuffer.insert(end, loc);
        // 写入文件
        try {
            FileUtil.writeString(stringBuffer.toString(), tags[2], CharsetUtil.CHARSET_UTF_8);
        } catch (IORuntimeException e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("保存接口处理异常：-2", e);
            return JsonMessage.getString(404, "保存接口处理异常：-2");
        }
        confService.reload(userName + " 操作了" + url + "地区屏蔽");
        return doApi(id);
    }

    private String doApi(String id) {
        try {
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", id);
            String res = HttpUtil.post(Config.Shield.getClearCache(), hashMap);
            if (!"ok".equals(res)) {
                return JsonMessage.getString(200, "接口返回：" + res);
            }
        } catch (Exception e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("接口访问异常", e);
            return JsonMessage.getString(404, "接口访问异常");
        }
        return JsonMessage.getString(200, "处理成功");
    }

    private StringBuffer createLocation(String tag, String id) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("\tlocation ").append(tag).append(" ").append("{").append("\t\n");
        stringBuffer.append("\t\t").append("proxy_pass       ").append(Config.Shield.getNginxProxyPass()).append(id).append("/;\n");
        stringBuffer.append("\t\t").append("tcp_nodelay      on;\n");
        stringBuffer.append("\t\t").append("proxy_set_header Host            $host;\n");
        stringBuffer.append("\t\t").append("proxy_set_header X-Real-IP       $remote_addr;\n");
        stringBuffer.append("\t\t").append("proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n");
        stringBuffer.append("\t}").append("\t\n");
        return stringBuffer;
    }

//    private String getShieldConfPath() {
//        return SystemBean.getInstance().getEnvironment().getProperty("shield.conf");
//    }


    private void saveJson(JSONObject jsonObject) throws IOException {
        String url = jsonObject.getString("url");
        JSONArray jsonArray = ShieldUtil.getJsonArray();
        Iterator<Object> iterator = jsonArray.iterator();
        while (iterator.hasNext()) {
            JSONObject object = (JSONObject) iterator.next();
            String oUrl = object.getString("url");
            if (oUrl.equals(url)) {
                iterator.remove();
            }
        }
        jsonArray.add(jsonObject);
        File file = new File(ShieldUtil.getShieldConfPath(), "info.conf");
        JsonUtil.saveJson(file.getPath(), jsonArray);
        //FileUtil.writeFile(file.getPath(), JsonUtil.formatJson(jsonArray.toString()));
    }

    private void delJson(JSONObject jsonObject) throws IOException {
        String url = jsonObject.getString("url");
        JSONArray jsonArray = ShieldUtil.getJsonArray();
        Iterator<Object> iterator = jsonArray.iterator();
        while (iterator.hasNext()) {
            JSONObject object = (JSONObject) iterator.next();
            String oUrl = object.getString("url");
            if (oUrl.equals(url)) {
                iterator.remove();
                break;
            }
        }
        File file = new File(ShieldUtil.getShieldConfPath(), "info.conf");
        JsonUtil.saveJson(file.getPath(), jsonArray);
        //FileUtil.writeFile(file.getPath(), JsonUtil.formatJson(jsonArray.toString()));
    }
}
